package com.cskaoyan.javase._0encapsulate._0introduction;

/**
 * 封装（encapsulate）是指将数据及相关操作绑定在一起的一种编程机制，使其构成一个不可分割的独立实体。
 * 在Java中，类就是这样一种结构。
 * 当然，数据被保护在类的内部，是为了尽可能地隐藏内部的细节，只保留一些对外"接口"使之与外部发生联系。
 * 之所以要封装，是为了将代码的使用者和实现者分开。
 * 使用者能够完全得到自己想要的功能，又不需要思考过多细节；
 * 实现者可以隐藏功能实现的细节，方便灵活进行修改而不影响使用者使用。
 * 封装的思想在生活中很典型的案例，就是各种电子产品。
 *
 * 从实际的语法角度上来说，Java当中的封装是依赖于访问权限修饰符来实现：
 *      比如完全不需要被外界知道的属性，在类中完全可以私有化。
 *      比如对外界不可见的一个性别 可用直接private修饰它
 *      这样用"对象名."就不可以在外界直接访问它了。
 * 而如果一个属性有在外界访问的需求，且希望能够实现对外界访问的控制，那就需要先私有化成员变量
 *      然后再提供访问的方法去实现访问的控制。
 *      Getter/Setter 方法。
 *      Getter/Setter方法的格式比较固定：
 *      Getter方法提供外界访问的途径，一般命名为getXxx（Xxx是成员变量名），一般直接返回成员变量得值即可。
 *      Setter方法提供外界赋值的途径，一般命名为setXxx（Xxx是成员变量名），一般使用this关键字完成赋值就可以了。
 *
 *
 * @since 15:04
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        // System.out.println(s.);
        // s.age = 300;

        s.setAge(120);
        System.out.println(s.getAge());
    }
}

class Student {
    // 需求1: 对外不能看到性别
    private String gender;

    // 需求2: name完全对外可见
    public String name;

    // 需求3: age属性我们希望能够控制外界的访问
    // 如果age对外直接有访问权限，是不能控制访问的，所以先私有化它
    private int age;

    // Getter方法对外提供访问的方式
    public int getAge() {
        return age;
    }

    // Setter方法对外提供赋值的方式
    public void setAge(int age) {
        /*
            age的取值是一个固定的范围
            [1,150]
         */
        if (age > 150) {
            System.out.println("您今年什么境界了?大概是筑基了吧!");
            return;
        }
        if (age < 1) {
            System.out.println("您活到过去了吗?");
            return;
        }
        // 正常的年龄,赋值成功
        this.age = age;
    }
}
